package com.whisperly.echotalk.starryb.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.preference.PreferenceManager;
import android.view.View;

import androidx.annotation.NonNull;

import com.google.android.material.snackbar.Snackbar;
import com.whisperly.echotalk.starryb.R;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendGmail {
    private static final String SYMBOLS = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    private static final long VERIFICATION_CODE_EXPIRY = 5 * 60 * 1000; // 5分钟
    private static final Map<String, VerificationCodeInfo> verificationCodes = new HashMap<>();

    // Gmail 配置
    private static final String GMAIL_USERNAME = "xchen6367@gmail.com";
    private static final String GMAIL_PASSWORD = "ifycmwfdmpfnufny";

    private static class VerificationCodeInfo {
        String code;
        long timestamp;
        String email;

        VerificationCodeInfo(String code, String email) {
            this.code = code;
            this.timestamp = System.currentTimeMillis();
            this.email = email;
        }

        boolean isValid() {
            return (System.currentTimeMillis() - timestamp) <= VERIFICATION_CODE_EXPIRY;
        }
    }

    /**
     * 生成验证码并与邮箱关联
     * @param email 用户邮箱
     * @return 生成的验证码
     */
    public static String generateCode(String email) {
        if (email == null || email.isEmpty()) {
            return null;
        }

        Random random = new Random();
        char[] nonceChars = new char[5];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLS.charAt(random.nextInt(SYMBOLS.length()));
        }

        String code = new String(nonceChars);
        // 将验证码与邮箱相关联并存储
        verificationCodes.put(email, new VerificationCodeInfo(code, email));

        return code;
    }

    /**
     * 检查验证码是否过期
     * ！！！注意：该方法返回true表示验证码已过期或不存在，false表示验证码有效！！！
     *
     * @param email 用户邮箱
     * @return true表示验证码已过期或不存在，false表示验证码有效
     */
    public static boolean isCodeValid(String email) {
        if (email == null || email.isEmpty()) {
            return true; // 邮箱为空，视为验证码无效
        }

        VerificationCodeInfo info = verificationCodes.get(email);
        // 如果info为null或者验证码已过期，返回true（表示验证码已过期）
        return info == null || !info.isValid();
    }

    /**
     * 检查验证码是否有效（名称更符合实际行为的替代方法）
     *
     * @param email 用户邮箱
     * @return true表示验证码有效，false表示验证码已过期或不存在
     */
    public static boolean isCodeNotExpired(String email) {
        if (email == null || email.isEmpty()) {
            return false; // 邮箱为空，视为验证码无效
        }

        VerificationCodeInfo info = verificationCodes.get(email);
        // 验证码存在且未过期
        return info != null && info.isValid();
    }

    /**
     * 检查验证码是否正确
     * @param email 用户邮箱
     * @param code 用户输入的验证码
     * @return 验证码是否正确
     */
    public static boolean isCodeCorrect(String email, String code) {
        if (email == null || email.isEmpty() || code == null || code.isEmpty()) {
            return false;
        }

        VerificationCodeInfo info = verificationCodes.get(email);
        return info != null && info.isValid() && info.code.equals(code);
    }

    /**
     * 获取指定邮箱的验证码
     * @param email 用户邮箱
     * @return 验证码，如果不存在或已过期则返回null
     */
    public static String getVerificationCode(String email) {
        if (email == null || email.isEmpty()) {
            return null;
        }

        VerificationCodeInfo info = verificationCodes.get(email);
        if (info != null && info.isValid()) {
            // 保持向后兼容性，返回 "email:code" 格式
            return email + ":" + info.code;
        }
        return null;
    }

    /**
     * 获取原始验证码值（不带邮箱前缀）
     * @param email 用户邮箱
     * @return 原始验证码值，如果不存在或已过期则返回null
     */
    public static String getRawVerificationCode(String email) {
        if (email == null || email.isEmpty()) {
            return null;
        }

        VerificationCodeInfo info = verificationCodes.get(email);
        if (info != null && info.isValid()) {
            return info.code;
        }
        return null;
    }

    /**
     * 配置Gmail SSL连接
     */
    private static void configureGmailSSL(Properties props) {
        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", "465");
    }

    /**
     * 配置Gmail TLS连接
     */
    private static void configureGmailTLS(Properties props) {
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.port", "587");
    }

    /**
     * 发送验证码邮件
     * @param email 收件人邮箱
     * @param view 用于显示Snackbar的视图
     * @param context 上下文
     */
    public static void sendEmail(String email, View view, Context context) {
        if (email == null || email.isEmpty()) {
            showSnackBar("red", view, context.getString(R.string.invalid_email_address), context);
            return;
        }

        // 获取当前用户选择的语言
        String languageCode = PreferenceManager.getDefaultSharedPreferences(context)
                .getString("language", "en");
        Locale locale = new Locale(languageCode);

        // 生成新的验证码
        String code = generateCode(email);
        if (code == null) {
            showSnackBar("red", view, context.getString(R.string.failed_to_generate_code), context);
            return;
        }

        final String verificationCode = code;

        new Thread(() -> {
            Properties props = new Properties();
            configureGmailSSL(props); // 使用SSL连接

            Session session = Session.getInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(GMAIL_USERNAME, GMAIL_PASSWORD);
                }
            });

            try {
                MimeMessage msg = new MimeMessage(session);
                String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date());

                msg.setFrom(new InternetAddress(GMAIL_USERNAME, "Blink Chat", "UTF-8"));
                msg.setRecipients(Message.RecipientType.TO, email);
                msg.setSubject(getLocalizedSubject(locale, context));
                msg.setSentDate(new Date());
                msg.setContent(getLocalizedEmailContent(locale, context, verificationCode, time), "text/html;charset=UTF-8");

                Transport.send(msg);
                showSnackBarOnUiThread("blue", view, context.getString(R.string.verification_code_sent), context);
            } catch (Exception e) {
                e.printStackTrace();
                showSnackBarOnUiThread("red", view, context.getString(R.string.failed_to_send_email), context);
            }
        }).start();
    }

    /**
     * 在UI线程上显示Snackbar
     */
    private static void showSnackBarOnUiThread(String type, View view, String content, Context context) {
        if (view == null || context == null) return;

        view.post(() -> showSnackBar(type, view, content, context));
    }

    /**
     * 显示Snackbar
     */
    public static void showSnackBar(String type, View view, String content, Context context) {
        if (view == null || context == null) return;

        int color;
        switch (type) {
            case "blue":
                color = context.getResources().getColor(R.color.colorBlue);
                break;
            case "red":
                color = context.getResources().getColor(R.color.colorRed);
                break;
            case "yellow":
                color = context.getResources().getColor(R.color.colorGold);
                break;
            default:
                color = context.getResources().getColor(R.color.colorBlue);
                break;
        }

        Snackbar snackbar = Snackbar.make(view, content, Snackbar.LENGTH_SHORT);
        snackbar.getView().setBackgroundColor(color);
        snackbar.show();
    }

    /**
     * 获取本地化的邮件主题
     */
    @NonNull
    private static String getLocalizedSubject(Locale locale, Context context) {
        Resources res = getLocalizedResources(context, locale);
        return res.getString(R.string.verification_email_subject);
    }

    /**
     * 获取本地化的邮件内容
     */
    @SuppressLint("SimpleDateFormat")
    @NonNull
    private static String getLocalizedEmailContent(Locale locale, Context context, String code, String time) {
        Resources res = getLocalizedResources(context, locale);

        String greeting = res.getString(R.string.verification_email_greeting);
        String message = res.getString(R.string.verification_email_message, code);
        String footer = res.getString(R.string.verification_email_footer);

        return "<div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 8px;\">\n" +
                "    <div style=\"text-align: center; margin-bottom: 20px;\">\n" +
                "        <h1 style=\"color: #ff9800;\">Blink Chat</h1>\n" +
                "    </div>\n" +
                "    <h3 style=\"font-size: 18px; color: #333;\">" + greeting + "</h3>\n" +
                "    <p style=\"font-size: 16px; color: #555; line-height: 1.5;\">" + message + "</p>\n" +
                "    <div style=\"background-color: #f5f5f5; padding: 15px; border-radius: 5px; text-align: center; margin: 20px 0;\">\n" +
                "        <span style=\"font-size: 24px; font-weight: bold; color: #ff9800; letter-spacing: 5px;\">" + code + "</span>\n" +
                "    </div>\n" +
                "    <p style=\"font-size: 14px; color: #777;\">" + footer + "</p>\n" +
                "    <div style=\"margin-top: 30px; border-top: 1px solid #e0e0e0; padding-top: 15px;\">\n" +
                "        <p style=\"font-size: 12px; color: #999; text-align: center;\">Blink Chat © " + new SimpleDateFormat("yyyy").format(new Date()) + "</p>\n" +
                "        <p style=\"font-size: 12px; color: #999; text-align: right;\">" + time + "</p>\n" +
                "    </div>\n" +
                "</div>";
    }

    /**
     * 获取特定区域设置的资源
     */
    private static Resources getLocalizedResources(Context context, Locale locale) {
        Resources standardResources = context.getResources();
        Configuration config = new Configuration(standardResources.getConfiguration());
        config.setLocale(locale);
        return context.createConfigurationContext(config).getResources();
    }
}